import { UUIDv4, wanZhengDiZhi } from '../gongJu/gongJu.js'
import { WuTi } from '../changJing/wuTi/WuTi.js'

// posetMessage 参数里面不能有函数
class WuLiWorker {
	worker = new Worker(new URL('./WuLiYinQing.js', import.meta.url), { type: 'module' })
	resolveMap = new Map()
	tingZhiMoNiZhuangTai = false

	constructor() {
		const worker = this.worker

		worker.onmessage = this.jieShou.bind(this)

		// worker.addEventListener('message', message => {}, { once: true })

		window.addEventListener('beforeunload', () => worker.terminate())
	}
	
	/**
	 * 发送信息
	 * @param {Object} xinXi 发送的信息
	 * @param {String} xinXi.mingZi
	 * @param {Object} xinXi.canShu
	 * @param {Boolean} xuYaoFanHui 是否需要返回promise信息
	 */
	faSong(xinXi, xuYaoFanHui) {
		xinXi.bianHao = UUIDv4()
		this.worker.postMessage(xinXi)
		
		if (xuYaoFanHui) {
			return new Promise(resolve => {
				this.resolveMap.set(xinXi.bianHao, resolve) // worker线程须有返回信息，避免resolve遗留
			})
		}
	}
	// 接收信息
	jieShou(xinXi) {
		let resolve = this.resolveMap.get(xinXi.data.bianHao)
		if (resolve) {
			resolve(xinXi.data.canShu)
			this.resolveMap.delete(xinXi.data.bianHao)
		}
	}

	// ammojs加载完成
	jiaZaiAmmo() {
		return this.faSong({
			mingZi: '加载ammo',
			canShu: {
				wasmDiZhi: wanZhengDiZhi('./wasm/ammo.wasm.wasm')
			}
		}, true)
	}
	// 页面隐藏
	yeMianYinCang(canShu) {
		return this.faSong({
			mingZi: 'yeMianYinCang',
			canShu: {
				yinCang: canShu
			}
		})
	}
	// 停止物理世界模拟
	tingZhiMoNi(canShu) {
		this.tingZhiMoNiZhuangTai = canShu
		
		return this.faSong({
			mingZi: 'tingZhiMoNi',
			canShu: {
				tingZhi: canShu
			}
		})
	}
	// 获取物理世界物体状态
	huoQuWuTi(jianGeShi) {
		return this.faSong({
			mingZi: 'huoQuWuTi',
			canShu: jianGeShi
		}, true)
	}
	// 操作物理引擎的物体
	gengXinCaoZuo() {
		this.faSong({
			mingZi: 'gengXinCaoZuo',
			canShu: wuTiCaoZuo
		}, true).then(canShu => {
			for (let bianHao in canShu) {
				let wuTi = WuTi.huoQuWuTi(bianHao)
				let cz = canShu[bianHao]
				
				if (wuTi) cz.forEach(c => wuTi.chuFaShiJian({ leiXing: c.mingZi, canShu: c.canShu }))
			}
		})
		
		for (let bianHao in wuTiCaoZuo) {
			let caoZuo = wuTiCaoZuo[bianHao]
			caoZuo.forEach(cz => {
				if (cz.mingZi == 'yiChuWuTi' || cz.mingZi == 'yiChuYueShu') delete wuTiCaoZuo[bianHao]
			})
			caoZuo.length = 0 //每帧清空操作
		}
	}
}

/**
 * 每帧发送给物理引擎的物体参数
 * @property {String} bianHao 物体编号
 * @property {Array<Object>} caoZuo 物体操作
 */
export let wuTiCaoZuo = {}

export const wuLiWorker = new WuLiWorker()